package cn.powerone.scm.service.impl;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import cn.powerone.common.utils.DateUtils;
import cn.powerone.common.utils.file.FileUploadUtils;
import cn.powerone.common.utils.poi.ExcelUtil;
import cn.powerone.scm.domain.*;
import cn.powerone.scm.pojo.bo.ScmInquiriesInOut;
import cn.powerone.scm.service.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.powerone.scm.mapper.ScmInquiriesOutMapper;
import org.springframework.web.multipart.MultipartFile;

/**
 * 供应商询价单Service业务层处理
 * 
 * @author PowerOne
 * @date 2025-07-02
 */
@Service
@RequiredArgsConstructor
public class ScmInquiriesOutServiceImpl implements IScmInquiriesOutService 
{
    private final ScmInquiriesOutMapper scmInquiriesOutMapper;

    private final IScmInquiriesInService scmInquiriesInService;

    private final IScmSupplierService scmSupplierService;

    private final IScmProjectsService scmProjectsService;

    private final IScmAttachmentLinkageService scmAttachmentLinkageService;

    /**
     * 查询供应商询价单
     * 
     * @param id 供应商询价单主键
     * @return 供应商询价单
     */
    @Override
    public ScmInquiriesOut selectScmInquiriesOutById(Long id)
    {
        return scmInquiriesOutMapper.selectScmInquiriesOutById(id);
    }

    /**
     * 查询供应商询价单列表
     * 
     * @param scmInquiriesOut 供应商询价单
     * @return 供应商询价单
     */
    @Override
    public List<ScmInquiriesOut> selectScmInquiriesOutList(ScmInquiriesOut scmInquiriesOut)
    {
        return scmInquiriesOutMapper.selectScmInquiriesOutList(scmInquiriesOut);
    }

    /**
     * 新增供应商询价单
     * 
     * @param scmInquiriesOut 供应商询价单
     * @return 结果
     */
    @Override
    public int insertScmInquiriesOut(ScmInquiriesOut scmInquiriesOut)
    {
        scmInquiriesOut.setCreateTime(DateUtils.getNowDate());
        return scmInquiriesOutMapper.insertScmInquiriesOut(scmInquiriesOut);
    }

    /**
     * 修改供应商询价单
     * 
     * @param scmInquiriesOut 供应商询价单
     * @return 结果
     */
    @Override
    public int updateScmInquiriesOut(ScmInquiriesOut scmInquiriesOut)
    {
        scmInquiriesOut.setUpdateTime(DateUtils.getNowDate());
        return scmInquiriesOutMapper.updateScmInquiriesOut(scmInquiriesOut);
    }

    /**
     * 批量删除供应商询价单
     * 
     * @param ids 需要删除的供应商询价单主键
     * @return 结果
     */
    @Override
    public int deleteScmInquiriesOutByIds(Long[] ids)
    {
        return scmInquiriesOutMapper.deleteScmInquiriesOutByIds(ids);
    }

    /**
     * 删除供应商询价单信息
     * 
     * @param id 供应商询价单主键
     * @return 结果
     */
    @Override
    public int deleteScmInquiriesOutById(Long id)
    {
        return scmInquiriesOutMapper.deleteScmInquiriesOutById(id);
    }

    @Override
    public int insertScmInquiriesOutFromIn(ScmInquiriesInOut scmInquiriesInOut) {
        //根据IDs查询询询价单
        ScmInquiriesIn scmInquiriesIn;
        ScmInquiriesOut scmInquiriesOut = new ScmInquiriesOut();
        ScmSupplier scmSupplier;
        int rows = 0;
        for (Long id : scmInquiriesInOut.getIds()){
            scmInquiriesIn = scmInquiriesInService.selectScmInquiriesInById(id);
            if (scmInquiriesIn == null) {continue;}
            scmInquiriesOut.setProjectId(scmInquiriesIn.getProjectId());
            scmInquiriesOut.setProductId(scmInquiriesIn.getProductId());
            scmInquiriesOut.setProjectProductId(scmInquiriesIn.getProjectProductId());
            scmInquiriesOut.setDrawingNumber(scmInquiriesIn.getDrawingNumber());
            scmInquiriesOut.setInternalVersion(scmInquiriesIn.getInternalVersion());
            scmInquiriesOut.setMaterial(scmInquiriesIn.getMaterial());
            scmInquiriesOut.setSpecification(scmInquiriesIn.getSpecification());
            scmInquiriesOut.setColor(scmInquiriesIn.getColor());
            scmInquiriesOut.setOnceQuantity(scmInquiriesIn.getOnceQuantity());
            scmInquiriesOut.setOnceUnit(scmInquiriesIn.getOnceUnit());
            scmInquiriesOut.setMonthlyQuantity(scmInquiriesIn.getMonthlyQuantity());
            scmInquiriesOut.setMonthlyUnit(scmInquiriesIn.getMonthlyUnit());
            scmInquiriesOut.setYearlyQuantity(scmInquiriesIn.getYearlyQuantity());
            scmInquiriesOut.setYearlyUnit(scmInquiriesIn.getYearlyUnit());
            scmInquiriesOut.setDisposableQuantity(scmInquiriesIn.getDisposableQuantity());
            scmInquiriesOut.setDisposableUnit(scmInquiriesIn.getDisposableUnit());
            scmInquiriesOut.setDisposableUnitPrice(scmInquiriesIn.getDisposableUnitPrice());
            scmInquiriesOut.setDisposableExpectedDeliveryDate(scmInquiriesIn.getDisposableExpectedDeliveryDate());
            scmInquiriesOut.setDisposableTryQuantity(scmInquiriesIn.getDisposableTryQuantity());
            scmInquiriesOut.setDisposableTryUnit(scmInquiriesIn.getDisposableTryUnit());
            scmInquiriesOut.setDisposableTryUnitPrice(scmInquiriesIn.getDisposableTryUnitPrice());
            scmInquiriesOut.setDisposableTryExpectedDeliveryDate(scmInquiriesIn.getDisposableTryExpectedDeliveryDate());
            scmInquiriesOut.setTryQuantity(scmInquiriesIn.getTryQuantity());
            scmInquiriesOut.setTryUnit(scmInquiriesIn.getTryUnit());
            scmInquiriesOut.setTryUnitPrice(scmInquiriesIn.getTryUnitPrice());
            scmInquiriesOut.setTryExpectedDeliveryDate(scmInquiriesIn.getTryExpectedDeliveryDate());
            scmInquiriesOut.setMassQuantity(scmInquiriesIn.getMassQuantity());
            scmInquiriesOut.setMassUnit(scmInquiriesIn.getMassUnit());
            scmInquiriesOut.setMassUnitPrice(scmInquiriesIn.getMassUnitPrice());
            scmInquiriesOut.setMassExpectedDeliveryDate(scmInquiriesIn.getMassExpectedDeliveryDate());
            scmInquiriesOut.setExpectedQuotationDate(scmInquiriesIn.getExpectedQuotationDate());
            scmInquiriesOut.setExpectedDeliveryDate(scmInquiriesIn.getExpectedDeliveryDate());
            scmInquiriesOut.setExpectedDatum(scmInquiriesIn.getExpectedDatum());
//            scmInquiriesOut.setRemarks(scmInquiriesIn.getRemarks());
//                scmInquiriesOut.setType(scmInquiriesIn.getType());

            //根据supplierIds 和 supplierNames，和查询结果，组装供应商询价单，并插入供应商询价单表
            for (int i = 0; i < scmInquiriesInOut.getSupplierIds().size(); i++){
                scmSupplier = scmSupplierService.selectScmSupplierById(scmInquiriesInOut.getSupplierIds().get(i));
                scmInquiriesOut.setSupplierId(scmInquiriesInOut.getSupplierIds().get(i));
                scmInquiriesOut.setSupplierName(scmSupplier.getNickname());
                rows = rows + scmInquiriesOutMapper.insertScmInquiriesOut(scmInquiriesOut);
            }
        }

        return rows;
    }

    @Override
    public void exportExcelByTemplate(HttpServletResponse response, List<ScmInquiriesOut> list, String templateName) throws IOException {
        if(!list.isEmpty()) {
            // 按照各供应商生成询价单
            Map<String, List<ScmInquiriesOut>> map = new HashMap<>();
            for (ScmInquiriesOut scmInquiriesOut : list) {
                String key = scmInquiriesOut.getSupplierName();
                if (map.containsKey(key)) {
                    map.get(key).add(scmInquiriesOut);
                } else {
                    map.put(key, new ArrayList<>());
                    List<ScmInquiriesOut> scmList = map.get(key);
                    scmList.add(scmInquiriesOut);
                }
            }

            // 读取模板并且按照供应商生成sheet
            InputStream templateStream = ExcelUtil.class.getClassLoader().getResourceAsStream("template/" + templateName);
            if (templateStream == null) {
                throw new FileNotFoundException("模板文件未找到");
            }
            Workbook workbook = WorkbookFactory.create(templateStream);

            boolean isFirst = true;
            for (Map.Entry<String, List<ScmInquiriesOut>> entry : map.entrySet()) {
                if (isFirst) {
                    workbook.setSheetName(0, entry.getKey());
                    isFirst = false;
                } else {
                    Sheet clonedSheet = workbook.cloneSheet(0);
                    int newSheetIndex = workbook.getSheetIndex(clonedSheet);
                    workbook.setSheetName(newSheetIndex, entry.getKey());
                }
            }

            String projectCode = null;
            Long projectId = null;
            // 按顺序填充工作表
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                Sheet sheet = workbook.getSheetAt(i);
                List<ScmInquiriesOut> listBySupplier = map.get(sheet.getSheetName());
                int totalInsert = listBySupplier.size() - 1;
                for (Row row : sheet) {
                    Cell cell = row.getCell(2);
                    if (cell !=null) {
                        if (cell.getCellType() == CellType.STRING && cell.getStringCellValue().contentEquals("${seq}")) {
                            int insertRowIndex = row.getRowNum() + 1;
                            int lastRowNum = sheet.getLastRowNum();
                            sheet.shiftRows(insertRowIndex, lastRowNum, totalInsert);
                            for (int j = 0; j < totalInsert; j++) {
                                Row newRow = sheet.createRow(insertRowIndex);
                                insertRowIndex++;
                                newRow.setHeight(row.getHeight());

                                // 复制所有单元格内容、样式和注释
                                for (int colIndex = 1; colIndex <= row.getLastCellNum(); colIndex++) {
                                    Cell sourceCell = row.getCell(colIndex);
                                    if (sourceCell == null) {
                                        continue;
                                    }

                                    // 创建目标单元格
                                    Cell targetCell = newRow.createCell(colIndex);

                                    // 复制单元格值
                                    ExcelUtil.copyCellValue(sourceCell, targetCell);

                                    // 复制单元格样式
                                    ExcelUtil.copyCellStyle(workbook, sourceCell, targetCell);

                                    // 复制单元格注释
                                    ExcelUtil.copyCellComment(sheet, sourceCell, targetCell);
                                }
                            }
                            break;
                        }
                    }
                }
                ScmInquiriesOut scmInquiriesOut = listBySupplier.get(0);
                ScmProjects scmProjects = scmProjectsService.selectScmProjectsByProjectId(scmInquiriesOut.getProjectId());
                ScmSupplier scmSupplier = scmSupplierService.selectScmSupplierById(scmInquiriesOut.getSupplierId());
                processSheetPlaceholders(sheet, scmProjects, scmSupplier, listBySupplier);
                projectCode = scmProjects.getProjectCode();
                projectId = scmInquiriesOut.getProjectId();
            }

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            workbook.write(response.getOutputStream());

            //保存文件并存储到attachment linkage table
            String fileUrl = FileUploadUtils.saveWorkbookToUploadPath(workbook, "project/"+projectCode,"RD询价单");
            ScmAttachmentLinkage scmAttachmentLinkage = new ScmAttachmentLinkage();
            scmAttachmentLinkage.setLinkedId(projectId);
            scmAttachmentLinkage.setDisplayCode(projectCode);
            scmAttachmentLinkage.setAttachmentType(2L); // 2:询价单
            scmAttachmentLinkage.setAttachmentUrl(fileUrl);
            scmAttachmentLinkageService.insertScmAttachmentLinkage(scmAttachmentLinkage);

            // 关闭工作簿
            workbook.close();
            templateStream.close();
        }
    }

    /**
     * 处理单个工作表中的占位符
     */
    private static void processSheetPlaceholders(Sheet sheet, ScmProjects scmProjects, ScmSupplier scmSupplier, List<ScmInquiriesOut> scmInquiriesOuts) {

        Map<String, String> supplierPlaceholders = getSupplierPlaceholders(scmProjects, scmSupplier);
        Map<String, String> inquiriesOutPlaceholders = new HashMap<>();

        int index = 0;
        boolean tableFlag = false;
        String updatedValue;
        for (Row row : sheet) {
            if (row.getCell(2) != null) {
                if (row.getCell(2).getStringCellValue().contentEquals("${seq}")) {
                    inquiriesOutPlaceholders = getInquiriesOutPlaceholders(scmInquiriesOuts.get(index), index+1);
                    index++;
                    tableFlag = true;
                }
            }
            for (Cell cell : row) {
                if (Objects.requireNonNull(cell.getCellType()) == CellType.STRING) {
                    String cellValue = cell.getStringCellValue();
                    if (cellValue.startsWith("${")) {
                        if (tableFlag) {
                            updatedValue = replacePlaceholders(cellValue, inquiriesOutPlaceholders);
                        } else {
                            updatedValue = replacePlaceholders(cellValue, supplierPlaceholders);
                        }
                        cell.setCellValue(updatedValue);
                        if (cellValue.contentEquals("${remarks}")) {
                            tableFlag = false;
                        }
                    }
                }
            }
        }
    }

    private static Map<String, String> getSupplierPlaceholders(ScmProjects scmProjects, ScmSupplier scmSupplier) {
        Map<String, String> placeholders = new HashMap<>();
        placeholders.put("supplierNo", scmSupplier.getSupplierNo());
        placeholders.put("supplierName", scmSupplier.getName());
        placeholders.put("supplierAddress", scmSupplier.getAddress());
        placeholders.put("supplierContact", scmSupplier.getLegalPerson());
        placeholders.put("supplierMobile", scmSupplier.getTelephone());

        if (scmSupplier.getEmail() == null) {
            placeholders.put("supplierEmail", "");
        } else {
            placeholders.put("supplierEmail", scmSupplier.getEmail());
        }

        if (scmProjects.getSupplierCurrency() == null) {
            placeholders.put("supplierCurrency", "");
        } else {
            placeholders.put("supplierCurrency", scmProjects.getSupplierCurrency());
        }
        return placeholders;
    }

    private static Map<String, String> getInquiriesOutPlaceholders(ScmInquiriesOut scmInquiriesOut, int seq) {
        Map<String, String> placeholders = new HashMap<>();
        placeholders.put("seq", String.valueOf(seq));
        placeholders.put("drawingNumber", scmInquiriesOut.getDrawingNumber());
        placeholders.put("version", scmInquiriesOut.getScmProjectProducts().getVersion());
        placeholders.put("productName", scmInquiriesOut.getScmProjectProducts().getProductName());
        BigDecimal onceQuantity = scmInquiriesOut.getOnceQuantity();
        placeholders.put("onceQuantity", onceQuantity.toString());
        BigDecimal monthlyQuantity = scmInquiriesOut.getMonthlyQuantity();
        placeholders.put("monthlyQuantity", monthlyQuantity.toString());
        BigDecimal yearlyQuantity = scmInquiriesOut.getYearlyQuantity();
        placeholders.put("yearlyQuantity", yearlyQuantity.toString());
        placeholders.put("model", scmInquiriesOut.getScmProjectProducts().getModel());
        placeholders.put("color", scmInquiriesOut.getScmProjectProducts().getColor());
        placeholders.put("material", scmInquiriesOut.getScmProjectProducts().getMaterial());
        placeholders.put("specification", scmInquiriesOut.getScmProjectProducts().getSpecification());
        placeholders.put("inflamingRetardingLevel", scmInquiriesOut.getScmProjectProducts().getInflamingRetardingLevel());
        BigDecimal tryQuantity = scmInquiriesOut.getTryQuantity();
        placeholders.put("tryQuantity", tryQuantity.toString());
        BigDecimal tryUnitPrice = scmInquiriesOut.getTryUnitPrice();
        placeholders.put("tryUnitPrice", tryUnitPrice.toString());
        Date tryExpectedDeliveryDate = scmInquiriesOut.getTryExpectedDeliveryDate();
        if (tryExpectedDeliveryDate == null)
            placeholders.put("tryExpectedDeliveryDate", "");
        else
            placeholders.put("tryExpectedDeliveryDate", DateUtils.dateTime(tryExpectedDeliveryDate));
        BigDecimal massQuantity = scmInquiriesOut.getMassQuantity();
        placeholders.put("massQuantity", massQuantity.toString());
        BigDecimal massUnitPrice = scmInquiriesOut.getMassUnitPrice();
        placeholders.put("massUnitPrice", massUnitPrice.toString());
        Date massExpectedDeliveryDate = scmInquiriesOut.getMassExpectedDeliveryDate();
        if (massExpectedDeliveryDate == null)
            placeholders.put("massExpectedDeliveryDate", "");
        else
            placeholders.put("massExpectedDeliveryDate", DateUtils.dateTime(massExpectedDeliveryDate));

        Date date = scmInquiriesOut.getExpectedQuotationDate();
        String dateString = null;
        if (date != null) {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            dateString = formatter.format(date);
        } else {
            dateString = "";
        }
        placeholders.put("expectedQuotationDate", dateString);

        if (scmInquiriesOut.getRemarks() == null) {
            placeholders.put("remarks", "");
        } else {
            placeholders.put("remarks", scmInquiriesOut.getRemarks());
        }
        return placeholders;
    }

    /**
     * 替换文本中的占位符
     */
    private static String replacePlaceholders(String text, Map<String, String> placeholders) {
        String result = text;
        for (Map.Entry<String, String> entry : placeholders.entrySet()) {
            String placeholder = "${" + entry.getKey() + "}";
            String replacement = entry.getValue();

            // 检查替换值是否为null，如果为null则用空字符串替换
            if (replacement == null) {
                replacement = "";
                System.out.println("警告: 占位符 " + placeholder + " 的值为null，已替换为空字符串");
            }

            System.out.println(entry.getKey() + "-" + entry.getValue());
            result = result.replace(placeholder, replacement);
        }
        return result;
    }

}
